/*
 * VANET simulator
 * 01-12-2010, Johan Lukkien and Tse
 *
 * This program simulates a collection of nodes with a periodic broadcasting behavior.
 */

#include "channel.h"
#include <math.h>

#ifndef M_PI
#define M_PI 3.14159265359
#endif

double Friis(double Pt, double Gt, double Gr, double lambda, double L, double d)
{
        /*
         * Friis free space propagation equation:
         *
         *       Pt * Gt * Gr * (lambda^2)
         *   P = --------------------------
         *       (4 *pi * d)^2 * L
         */
  double M = lambda / (4 * M_PI * d);
  return (Pt * Gt * Gr * (M * M)) / L;
}

double TwoRay(double Pt, double Gt, double Gr, double ht, double hr, double L, double d, double lambda)
{
        /*
         *  if d < crossover_dist, use Friis free space model
         *  if d >= crossover_dist, use two ray model
         *
         *  Two-ray ground reflection model.
         *
         *	     Pt * Gt * Gr * (ht^2 * hr^2)
         *  Pr = ----------------------------
         *           d^4 * L
         *
         * The original equation in Rappaport's book assumes L = 1.
         * To be consistant with the free space equation, L is added here.
         */

	double Pr;  // received power
	double crossover_dist = (4 * M_PI * ht * hr) / lambda;

	if (d < crossover_dist)
	{
        Pr = Friis(Pt, Gt, Gr, lambda, L, d);
        //printf("Friis: %e\n", Pr);
    }
	else
	{
    	Pr = Pt * Gt * Gr * (hr * hr * ht * ht) / (d * d * d * d * L);
       //printf("Tworay: %e\n", Pr);    
    }		
	return Pr;
}

double getDist(double Pr, double Pt, double Gt, double Gr, double hr, double ht, double L, double lambda)
{        
       /* Get quartic root */
       return sqrt(sqrt(Pt * Gt * Gr * (hr * hr * ht * ht) / Pr));
         
}

double getDistFriis(double Pr, double Pt, double Gt, double Gr, double lambda)
{
        /*
         * Friis free space propagation equation:
         *
         *            Pt * Gt * Gr      lambda
         *  d  = sqrt(-------------)   *--------
         *             Pr * L            4*pi
         */
  double M = lambda / (4 * M_PI);
  return sqrt((Pt * Gt * Gr) / Pr)*M;
}
